package cn.lotusnut.dynamicscheduled.configurer;

import cn.lotusnut.dynamicscheduled.entity.task.TaskEntity;
import cn.lotusnut.dynamicscheduled.service.TaskEntityService;
import cn.lotusnut.dynamicscheduled.util.TaskUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTask;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.config.TriggerTask;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @Author JiangMing Zhou
 * @Date 2023/4/23 10:08
 * @Version 1.8
 */
@Configuration
@Slf4j
public class DynamicScheduledConfigurer implements SchedulingConfigurer {
    @Resource
    private TaskEntityService taskEntityService;

    private static ScheduledTaskRegistrar scheduledTaskRegistrar;

    private static Map<String, TriggerTask> triggerTaskMap;

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        log.info("定时任务注册器：{}",scheduledTaskRegistrar);
        DynamicScheduledConfigurer.scheduledTaskRegistrar = scheduledTaskRegistrar;
        List<TaskEntity> taskEntities = taskEntityService.selectTaskEntityList();
        if (!CollectionUtils.isEmpty(taskEntities)){
            initTasks(taskEntities);
        }
    }


    private void initTasks(List<TaskEntity> taskEntities){
        log.info("开始初始化定时任务");
        triggerTaskMap = new HashMap<>();
        taskEntities.forEach(taskEntity -> {
            Runnable runnable = TaskUtil.getRunnable(taskEntity);
            Trigger trigger = TaskUtil.getTrigger(taskEntity);
            TriggerTask triggerTask = new TriggerTask(runnable, trigger);
            triggerTaskMap.put(taskEntity.getTaskId(), triggerTask);
            log.info("初始化定时任务：{}",taskEntity.getTaskId());
        });
        scheduledTaskRegistrar.afterPropertiesSet();
        log.info("初始化定时任务结束");
    }

    public synchronized boolean run(String taskId){
        TriggerTask triggerTask = triggerTaskMap.get(taskId);
        if (ObjectUtils.isEmpty(triggerTask)){
            return false;
        }
        triggerTask.getRunnable().run();
        return true;
    }

    public synchronized boolean stop(String taskId){
        log.info("准备停止定时任务：{}",taskId);
        TriggerTask triggerTask = triggerTaskMap.get(taskId);
        if (ObjectUtils.isEmpty(triggerTask)){
            log.info("未找到定时任务：{}",taskId);
            return false;
        }
        Set<ScheduledTask> scheduledTasks = scheduledTaskRegistrar.getScheduledTasks();
        for (ScheduledTask scheduledTask : scheduledTasks) {
            if (triggerTask.getRunnable() == scheduledTask.getTask().getRunnable()){
                scheduledTask.cancel();
                triggerTaskMap.remove(taskId);
                log.info("停止定时任务：{}",taskId);
                return true;
            }
        }
        return false;
    }

    public synchronized void start(TaskEntity taskEntity){
        log.info("准备启动定时任务：{}",taskEntity.getTaskId());
        Runnable runnable = TaskUtil.getRunnable(taskEntity);
        Trigger trigger = TaskUtil.getTrigger(taskEntity);
        TriggerTask triggerTask = new TriggerTask(runnable, trigger);
        triggerTaskMap.put(taskEntity.getTaskId(), triggerTask);
        log.info("启动定时任务：{}",taskEntity.getTaskId());
    }

}
